package com.oazon.sonos.core;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.StringRequest;
import com.oazon.common.TaskHelper;
import com.oazon.common.util.RequestManager;
import com.oazon.common.util.Utils;
import com.oazon.moco.bean.McServiceMsg;
import com.oazon.sonos.listener.SonosListener;
import com.oazon.sonos.util.IParse;
import com.oazon.sonos.util.MediaCollectionParse;
import com.oazon.sonos.util.MediaMetadataParse;
import com.oazon.sonos.util.MediaUriParse;
import com.oazon.sonos.util.SearchResponseParse;
import com.oazon.sonos.util.XmlProcess;

public abstract class AbsServiceHelper {

	protected final String TAG = "RequestHelper";
	protected Context context;
	protected String sHeader;
	protected String url;
	private void getSoapResult(final String url, String sHeader,
			final String body, String soapActions,
			final SonosListener listener, final IParse parse) {
		if (listener == null) {
			return;
		}

		String sBody = "<s:Body>" + body + "</s:Body>";
		final String data = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
				+ sHeader + sBody + "</s:Envelope>";

		final String contentType = "text/xml; charset=\"utf-8\"";

		Log.d(TAG, "getSoapResult url:" + url + " sHeader:" + sHeader
				+ " sbody:" + sBody + "soapActions:" + soapActions);
		try {

			final Map<String, String> headMaps = new HashMap<String, String>();
			headMaps.put("SOAPACTION", soapActions);
			// headMaps.put("CONTENT-TYPE", contentType);
			headMaps.put("ACCEPT-LANGUAGE", "zh-CN,en-US;q=0.9");
			headMaps.put("User-Agent", "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A334 Safari/7534.48.3");
			try {
				if (!Utils.isWifiConnectedOrConnecting(context)) {
					Toast.makeText(context, "WiFi未连接", Toast.LENGTH_SHORT)
							.show();
				}
				RequestQueue queue = RequestManager.getRequestQueue();

				StringRequest request = new StringRequest(Method.POST, url,
						new Response.Listener<String>() {

							@Override
							public void onResponse(String xml) {
								Log.d(TAG, "xxx" + xml);
								xml = XmlProcess.processXml(xml);
								Object result = null;
								IParse newParse = parse;
								if (newParse == null) {
									if (isCollection(xml)) {
										newParse = MediaCollectionParse
												.getInstance();
									} else if (isMediaMetadata(xml)) {
										newParse = MediaMetadataParse
												.getInstance();
									}else{
										newParse = null;
									}
								}

								if (newParse != null) {
									try {
										result = newParse
												.parse(new ByteArrayInputStream(
														xml.getBytes(HTTP.UTF_8)));
									} catch (UnsupportedEncodingException e) {
										e.printStackTrace();
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
								listener.onResponse(result);

							}
						}, new Response.ErrorListener() {

							@Override
							public void onErrorResponse(VolleyError error) {
								if (error != null)
									listener.onError(0, error.getMessage());

							}
						}) {

					@Override
					public Map<String, String> getHeaders()
							throws AuthFailureError {
						return headMaps;
					}

					@Override
					public byte[] getBody() throws AuthFailureError {
						try {
							return data.getBytes(HTTP.UTF_8);
						} catch (Exception e) {
							Log.d(TAG, "getBody Error: " + e.getMessage());
							return null;
						}
					}

					@Override
					public String getBodyContentType() {
						return contentType;
					}
				};
				queue.add(request);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			Log.d(TAG, "Exception" + e.getMessage());
			e.printStackTrace();
		}

	}

	public void getMetadata(String id, int index, int count,
			SonosListener listener) {
		String cmd = "<getMetadata xmlns=\"http://www.sonos.com/Services/1.1\">"
				+ "<id>"
				+ id
				+ "</id>"
				+ "<index>"
				+ index
				+ "</index>"
				+ "<count>" + count + "</count>" + "</getMetadata>";
		String getMetadataActions = "http://www.sonos.com/Services/1.1#getMetadata";
		getSoapResult(url, sHeader, cmd, getMetadataActions, listener, null);

	}

	public void getMediaURI(String id, SonosListener listener) {
		String cmd = "<getMediaURI xmlns=\"http://www.sonos.com/Services/1.1\">"
				+ "<id>" + id + "</id>" + "</getMediaURI>";
		String getMediaURIActions = "http://www.sonos.com/Services/1.1#getMediaURI";
		getSoapResult(url, sHeader, cmd, getMediaURIActions, listener,
				MediaUriParse.getInstance());

	}

	public void search(String id, int index, int count, String term,
			SonosListener listener) {
		String cmd = "<search xmlns=\"http://www.sonos.com/Services/1.1\">"
				+ "<id>" + id + "</id>" + "<term>" + term + "</term>"
				+ "<index>" + index + "</index>" + "<count>" + count
				+ "</count>" + "</search>";
		String searchActions = "http://www.sonos.com/Services/1.1#search";
		getSoapResult(url, sHeader, cmd, searchActions, listener,
				SearchResponseParse.getInstance());
	}

	private boolean isCollection(String str) {
		if (str.indexOf("<mediaCollection>") >= 0) {
			return true;
		}
		return false;
	}

	private boolean isMediaMetadata(String str) {
		if (str.indexOf("<mediaMetadata>") >= 0) {
			return true;
		}
		return false;
	}

	public abstract void registMcServiceMsg(McServiceMsg msg);
	
	public abstract McServiceMsg getMcServiceMsg();
}
